"""
试卷管理模块 - 权限控制
"""
from rest_framework import permissions


class CanManageExamPaper(permissions.BasePermission):
    """
    可以管理试卷的权限
    """

    def has_permission(self, request, view):
        """检查基本权限"""
        if not request.user.is_authenticated:
            return False

        # 创建和管理试卷需要教师或管理员权限
        if request.user.is_admin_user or request.user.is_teacher:
            return True

        return False

    def has_object_permission(self, request, view, obj):
        """检查对象权限"""
        # 管理员可以管理所有试卷
        if request.user.is_admin_user:
            return True

        # 试卷创建者可以管理
        if obj.creator == request.user:
            return True

        return False


class CanViewExamPaper(permissions.BasePermission):
    """
    可以查看试卷的权限
    """

    def has_object_permission(self, request, view, obj):
        """检查对象权限"""
        # 管理员可以查看所有试卷
        if request.user.is_admin_user:
            return True

        # 学生只能查看已发布的公开试卷
        if request.user.is_student:
            return obj.status == 'published' and obj.is_public

        # 教师可以查看自己创建的试卷和公开试卷
        if request.user.is_teacher:
            return obj.creator == request.user or obj.is_public

        return False


class CanManageTemplate(permissions.BasePermission):
    """
    可以管理试卷模板的权限
    """

    def has_permission(self, request, view):
        """检查基本权限"""
        if not request.user.is_authenticated:
            return False

        # 创建和管理模板需要教师或管理员权限
        if request.user.is_admin_user or request.user.is_teacher:
            return True

        return False

    def has_object_permission(self, request, view, obj):
        """检查对象权限"""
        # 管理员可以管理所有模板
        if request.user.is_admin_user:
            return True

        # 模板创建者可以管理
        if obj.creator == request.user:
            return True

        # 对于公开模板，教师可以使用但不能修改
        if obj.is_public and request.user.is_teacher and request.method in permissions.SAFE_METHODS:
            return True

        return False


class CanAccessPaperAnalysis(permissions.BasePermission):
    """
    可以访问试卷分析的权限
    """

    def has_permission(self, request, view):
        """检查基本权限"""
        if not request.user.is_authenticated:
            return False

        # 只有教师和管理员可以访问分析功能
        return request.user.is_admin_user or request.user.is_teacher

    def has_object_permission(self, request, view, obj):
        """检查对象权限"""
        # 管理员可以查看所有分析
        if request.user.is_admin_user:
            return True

        # 试卷创建者可以查看相关分析
        if obj.exam_paper.creator == request.user:
            return True

        return False


class IsPaperOwnerOrReadOnly(permissions.BasePermission):
    """
    试卷所有者或只读权限
    """

    def has_object_permission(self, request, view, obj):
        """检查对象权限"""
        # 读取权限对所有认证用户开放（在get_queryset中进一步过滤）
        if request.method in permissions.SAFE_METHODS:
            return True

        # 管理员和试卷创建者可以修改
        return obj.creator == request.user or request.user.is_admin_user


class CanPublishExamPaper(permissions.BasePermission):
    """
    可以发布试卷的权限
    """

    def has_object_permission(self, request, view, obj):
        """检查对象权限"""
        # 管理员可以发布所有试卷
        if request.user.is_admin_user:
            return True

        # 只有试卷创建者可以发布自己的试卷
        return obj.creator == request.user


class CanReviewExamPaper(permissions.BasePermission):
    """
    可以审核试卷的权限
    """

    def has_permission(self, request, view):
        """检查基本权限"""
        if not request.user.is_authenticated:
            return False

        # 只有教师和管理员可以审核试卷
        return request.user.is_admin_user or request.user.is_teacher

    def has_object_permission(self, request, view, obj):
        """检查对象权限"""
        # 管理员可以审核所有试卷
        if request.user.is_admin_user:
            return True

        # 教师不能审核自己创建的试卷
        if obj.creator == request.user:
            return False

        return True


class IsTemplatePublicOrOwner(permissions.BasePermission):
    """
    公开模板或模板所有者权限
    """

    def has_object_permission(self, request, view, obj):
        """检查对象权限"""
        # 读取权限对所有认证用户开放
        if request.method in permissions.SAFE_METHODS:
            return True

        # 管理员和模板创建者可以修改
        return obj.creator == request.user or request.user.is_admin_user


class HasExamPaperAccess(permissions.BasePermission):
    """
    具有试卷访问权限的综合检查
    """

    def has_permission(self, request, view):
        """检查基本权限"""
        if not request.user.is_authenticated:
            return False

        # 列表视图权限在get_queryset中控制
        if view.action == 'list':
            return True

        # 创建操作需要教师权限
        if view.action == 'create':
            return request.user.is_admin_user or request.user.is_teacher

        return True

    def has_object_permission(self, request, view, obj):
        """根据不同操作检查权限"""
        if view.action in ['retrieve']:
            return CanViewExamPaper().has_object_permission(request, view, obj)

        elif view.action in ['update', 'partial_update', 'destroy']:
            return CanManageExamPaper().has_object_permission(request, view, obj)

        elif view.action in ['publish', 'analyze', 'review']:
            return CanManageExamPaper().has_object_permission(request, view, obj)

        elif view.action in ['create_version', 'add_questions', 'export_paper']:
            return CanManageExamPaper().has_object_permission(request, view, obj)

        return False


class HasTemplateAccess(permissions.BasePermission):
    """
    具有模板访问权限的综合检查
    """

    def has_permission(self, request, view):
        """检查基本权限"""
        if not request.user.is_authenticated:
            return False

        # 列表视图权限在get_queryset中控制
        if view.action == 'list':
            return True

        # 创建操作需要教师权限
        if view.action == 'create':
            return request.user.is_admin_user or request.user.is_teacher

        return True

    def has_object_permission(self, request, view, obj):
        """根据不同操作检查权限"""
        if view.action in ['retrieve']:
            return IsTemplatePublicOrOwner().has_object_permission(request, view, obj)

        elif view.action in ['update', 'partial_update', 'destroy']:
            return CanManageTemplate().has_object_permission(request, view, obj)

        elif view.action in ['generate_paper', 'clone']:
            return CanManageTemplate().has_object_permission(request, view, obj)

        elif view.action in ['set_public']:
            # 只有模板所有者或管理员可以设置公开状态
            return obj.creator == request.user or request.user.is_admin_user

        return False


class IsPaperPublished(permissions.BasePermission):
    """
    检查试卷是否已发布
    """

    def has_object_permission(self, request, view, obj):
        """检查试卷状态"""
        # 学生只能访问已发布的试卷
        if request.user.is_student:
            return obj.status == 'published'

        # 教师和管理员可以访问所有状态的试卷
        return True


class IsPaperInReviewableState(permissions.BasePermission):
    """
    检查试卷是否处于可审核状态
    """

    def has_object_permission(self, request, view, obj):
        """检查试卷状态"""
        return obj.status == 'draft'


class IsPaperInPublishableState(permissions.BasePermission):
    """
    检查试卷是否处于可发布状态
    """

    def has_object_permission(self, request, view, obj):
        """检查试卷状态"""
        return obj.status == 'reviewed'


class CanUseTemplate(permissions.BasePermission):
    """
    可以使用模板的权限
    """

    def has_object_permission(self, request, view, obj):
        """检查对象权限"""
        # 管理员可以使用所有模板
        if request.user.is_admin_user:
            return True

        # 模板所有者可以使用
        if obj.creator == request.user:
            return True

        # 公开的模板可以被所有教师使用
        if obj.is_public and request.user.is_teacher:
            return True

        return False


class CanExportExamPaper(permissions.BasePermission):
    """
    可以导出试卷的权限
    """

    def has_object_permission(self, request, view, obj):
        """检查对象权限"""
        # 管理员可以导出所有试卷
        if request.user.is_admin_user:
            return True

        # 试卷创建者可以导出
        if obj.creator == request.user:
            return True

        # 已发布的公开试卷可以被教师导出
        if obj.status == 'published' and obj.is_public and request.user.is_teacher:
            return True

        return False


class HasPaperSectionAccess(permissions.BasePermission):
    """
    具有试卷部分访问权限
    """

    def has_permission(self, request, view):
        """检查基本权限"""
        if not request.user.is_authenticated:
            return False

        # 创建和修改需要管理试卷的权限
        if view.action in ['create', 'update', 'partial_update', 'destroy']:
            return request.user.is_admin_user or request.user.is_teacher

        return True

    def has_object_permission(self, request, view, obj):
        """检查对象权限"""
        # 通过关联的试卷检查权限
        return CanManageExamPaper().has_object_permission(request, view, obj.exam_paper)


class HasPaperQuestionAccess(permissions.BasePermission):
    """
    具有试卷题目访问权限
    """

    def has_permission(self, request, view):
        """检查基本权限"""
        if not request.user.is_authenticated:
            return False

        # 创建和修改需要管理试卷的权限
        if view.action in ['create', 'update', 'partial_update', 'destroy']:
            return request.user.is_admin_user or request.user.is_teacher

        return True

    def has_object_permission(self, request, view, obj):
        """检查对象权限"""
        # 通过关联的试卷检查权限
        return CanManageExamPaper().has_object_permission(request, view, obj.exam_paper)


class HasVersionAccess(permissions.BasePermission):
    """
    具有版本访问权限
    """

    def has_permission(self, request, view):
        """检查基本权限"""
        if not request.user.is_authenticated:
            return False

        # 只有教师和管理员可以访问版本功能
        return request.user.is_admin_user or request.user.is_teacher

    def has_object_permission(self, request, view, obj):
        """检查对象权限"""
        # 管理员可以访问所有版本
        if request.user.is_admin_user:
            return True

        # 试卷创建者可以访问版本
        if obj.exam_paper.creator == request.user:
            return True

        return False


class CanRestoreVersion(permissions.BasePermission):
    """
    可以恢复版本的权限
    """

    def has_object_permission(self, request, view, obj):
        """检查对象权限"""
        # 管理员可以恢复所有版本
        if request.user.is_admin_user:
            return True

        # 只有试卷创建者可以恢复版本
        return obj.exam_paper.creator == request.user